// net/NetClient.dart
import 'dart:io';
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:metaera_flutter/utils/Device.dart';
import '../widgets/Toasts.dart';

class NetClient {
  static final NetClient _instance = NetClient._internal();
  late Dio _dio;

  // 添加基础URL配置
  final String _baseUrl = 'https://api.metaera.hk/'; // 根据实际域名修改

  factory NetClient() => _instance;

  NetClient._internal() {
    BaseOptions options = BaseOptions(
      baseUrl: _baseUrl, // 设置基础URL
      connectTimeout: const Duration(seconds: 10),
      receiveTimeout: const Duration(seconds: 10),
      headers: {'Accept': 'application/json'},
    );

    _dio = Dio(options);

    (_dio.httpClientAdapter as IOHttpClientAdapter).onHttpClientCreate =
        (HttpClient client) {
          client.badCertificateCallback =
              (X509Certificate cert, String host, int port) {
                return true;
              };
          return client;
        };
  }

  // GET请求
  Future<Map<String, dynamic>> get(
    String path, {
    Map<String, dynamic>? params,
  }) async {
    try {
      Options options = Options();
      _addDefaultHeaders(options);

      final response = await _dio.get(
        path,
        queryParameters: params,
        options: options,
      );

      if (response.statusCode == 200) {
        // 处理 response.data，如果是字符串则转换为 Map
        if (response.data is Map<String, dynamic>) {
          return response.data as Map<String, dynamic>;
        } else if (response.data is String) {
          try {
            final decoded = jsonDecode(response.data as String);
            if (decoded is Map<String, dynamic>) {
              return decoded;
            } else {
              Toasts.error('解析后的数据不是Map类型');
              throw HttpException('GET请求解析后的数据不是Map类型');
            }
          } catch (e) {
            Toasts.error('JSON解析失败');
            throw HttpException('GET请求JSON解析失败: $e');
          }
        } else {
          Toasts.error('响应数据格式错误');
          throw HttpException('GET请求响应数据类型错误: ${response.data.runtimeType}');
        }
      } else {
        Toasts.error('请求失败: ${response.statusCode}');
        throw HttpException('GET请求失败: ${response.statusCode}');
      }
    } on DioException catch (e) {
      Toasts.error("请求失败: ${e.message}'");
      throw HttpException('GET请求失败: ${e.message}');
    }
  }

  // POST请求
  Future<Map<String, dynamic>> post(
    String path, {
    Map<String, dynamic>? body,
  }) async {
    try {
      Options options = Options(contentType: 'application/json');
      _addDefaultHeaders(options);

      final response = await _dio.post(path, data: body, options: options);

      if (response.statusCode == 200) {
        // 处理 response.data，如果是字符串则转换为 Map
        if (response.data is Map<String, dynamic>) {
          return response.data as Map<String, dynamic>;
        } else if (response.data is String) {
          try {
            final decoded = jsonDecode(response.data as String);
            if (decoded is Map<String, dynamic>) {
              return decoded;
            } else {
              Toasts.error('解析后的数据不是Map类型');
              throw HttpException('POST请求解析后的数据不是Map类型');
            }
          } catch (e) {
            Toasts.error('JSON解析失败');
            throw HttpException('POST请求JSON解析失败: $e');
          }
        } else {
          Toasts.error('响应数据格式错误');
          throw HttpException('POST请求响应数据类型错误: ${response.data.runtimeType}');
        }
      } else {
        Toasts.error('请求失败: ${response.statusCode}');
        throw HttpException('POST请求失败: ${response.statusCode}');
      }
    } on DioException catch (e) {
      Toasts.error("请求失败: ${e.message}'");
      throw HttpException('POST请求失败: ${e.message}');
    }
  }

  // 添加默认header信息
  void _addDefaultHeaders(Options options) {
    options.headers ??= {};
    options.headers?['os'] = Platform.operatingSystem;
    options.headers?['deviceid'] = DeviceUtils.getDeviceId();
  }

  // 关闭客户端
  void close() {
    // Dio不需要手动关闭
  }
}
